/*
 * Licensed to the ConArtist Development Team (CADT).
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 * The CADT licenses this file to you under the Apache License, 
 * Version 2.0 (the "License"); you may not use this file except in
 * compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <sys/stat.h>

#include <apr_file_io.h>
#include <apr_strings.h>

#include "conartist.h"
#include "caLog.h"

#include "caPrivate.h"

apr_status_t checkDirectory(const char *fspath, int create)
{
    apr_finfo_t fi;
    apr_status_t rv;

    if (!fspath)
        return APR_EINVAL;

    rv = apr_stat(&fi, fspath, APR_FINFO_TYPE, globalPool);
    if (rv == APR_SUCCESS && fi.filetype != APR_DIR) {
        caLog(CA_LOG_ERROR, "Can't use directory '%s' as it exists "
              "and is not a directory", fspath);
        return APR_EINVAL;
    } else if (rv != APR_SUCCESS && create) {
        rv = mkdir(fspath,
                   S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR|S_IXUSR|S_IXGRP|S_IXOTH);
        if (rv == 0) {
            caLog(CA_LOG_INFO, "Created directory '%s'", fspath);
            return APR_SUCCESS;
        } else {
            caLog(CA_LOG_WARN, "Unable to create directory '%s'", fspath);
            rv = APR_EINVAL;
        }
    }
    return rv;
}

apr_status_t caRecurseCheckDirectory(const char *base, const char *extra)
{
    apr_status_t rv = APR_SUCCESS;
    char *ptr, *slash = NULL, *cp;
    char *fspath;

    cp = apr_pstrdup(globalPool, extra);
    ptr = cp;

    while ((slash = strchr(ptr, '/'))) {
        if (slash != cp) {
            *slash = '\0';
            rv = apr_filepath_merge(&fspath, base, 
                                    (cp[0] == '/' ? &cp[1] : cp), 
                                    0, globalPool);
            *slash = '/';
            if (rv != APR_SUCCESS)
                break;
            rv = checkDirectory(fspath, 1);
            if (rv != APR_SUCCESS)
                break;
        }
        ptr = slash + 1;
    }
    if (rv == APR_SUCCESS && *ptr != '\0') {
        if (strchr(ptr, '.') == NULL) {
            rv = apr_filepath_merge(&fspath, base, cp, 0, globalPool);
            if (rv == APR_SUCCESS)
                rv = checkDirectory(fspath, 1);
        }
    }

    return rv;
}

apr_status_t caFileWrite(const char *fn, const char *buf, apr_size_t bLen)
{
    apr_status_t rv;
    apr_file_t *fh = NULL;

    rv = apr_file_open(&fh, fn, APR_CREATE|APR_TRUNCATE|APR_WRITE,
                       APR_OS_DEFAULT, globalPool);
    if (rv == APR_SUCCESS) {
        apr_size_t actualWrite = 0;
        rv = apr_file_write_full(fh, buf, bLen, &actualWrite);
        apr_file_close(fh);
    }
    return rv;
}
